# coding: utf-8
import datetime
import json
import time

import sqlalchemy as sa

from .ext import orm


class ModelJSONfyMixin(object):

    @classmethod
    def _get_columns(cls):
        return (c.name for c in cls.__table__.columns)

    def to_json(self, excludes=None):
        excludes = excludes or []
        columns = set(self._get_columns()) - set(excludes)
        fields = {}

        for col in columns:
            data = self.__getattribute__(col)
            try:
                # this will fail on non-encodable values, like other classes
                json.dumps(data)
                fields[col] = data
            except TypeError:
                if isinstance(data, datetime.datetime):
                    fields[col] = time.mktime(data.timetuple())
                elif isinstance(data, datetime.date):
                    fields[col] = data.isoformat()
                elif isinstance(data, datetime.timedelta):
                    fields[col] = (datetime.datetime.min + data).time().isoformat()
                else:
                    fields[col] = None
        return fields


class Domain(orm.Model, ModelJSONfyMixin):

    __tablename__ = 'domains'

    id = orm.Column(orm.Integer, primary_key=True, autoincrement=True)
    domain_id = orm.Column(orm.String(10))
    domain_name = orm.Column(orm.String(30), unique=True)
    cname = orm.Column(orm.String(120))
    connect_in = orm.Column(orm.String(30))
    test_url = orm.Column(orm.String(120))
    region = orm.Column(orm.String(30))
    protocol = orm.Column(orm.String(30))
    bandwidth_peak = orm.Column(orm.Integer)
    cache_size = orm.Column(orm.Integer)
    set_filter = orm.Column(orm.Boolean,
                            default=False,
                            server_default=sa.sql.expression.false())
    status = orm.Column(orm.String(10),
                        default='ON',
                        server_default='ON')
    project_id = orm.Column(orm.String(30))
    creator = orm.Column(orm.String(30))
    create_time = orm.Column(orm.DateTime,
                             default=datetime.datetime.now())

    def __init__(self, resource_id, domain_name,
                 cname, connect_in, region, protocol, project_id,
                 bandwidth_peak, cache_size,
                 creator, test_url, set_filter=False,
                 status='ON', create_time=None):
        self.domain_id = resource_id
        self.domain_name = domain_name
        self.cname = cname
        self.connect_in = connect_in
        self.region = region
        self.bandwidth_peak = bandwidth_peak
        self.cache_size = cache_size
        self.set_filter = set_filter
        self.protocol = protocol
        self.project_id = project_id
        self.creator = creator
        self.test_url = test_url
        self.status = status
        self.create_time = create_time or datetime.datetime.now()


class DomainCache(orm.Model, ModelJSONfyMixin):

    __tablename__ = 'domain_cache'

    id = orm.Column(orm.Integer, primary_key=True, autoincrement=True)
    domain_id = orm.Column(orm.String(10), nullable=False)
    domain_cache_id = orm.Column(orm.String(10), nullable=False)
    priority = orm.Column(orm.Integer,
                          default=1,
                          server_default=u'1')
    media_type = orm.Column(orm.String(10))
    url_template = orm.Column(orm.String(10))
    ttl = orm.Column(orm.Integer)
    unit = orm.Column(orm.String(10),
                      default=u'天',
                      server_default=u'天')
    enabled = orm.Column(orm.Boolean,
                         default=False,
                         server_default=sa.sql.expression.false(),
                         nullable=False)


class ActionLog(orm.Model, ModelJSONfyMixin):

    __tablename__ = 'action_log'

    id = orm.Column(orm.Integer, primary_key=True, autoincrement=True)
    username = orm.Column(orm.String(10), nullable=False)
    resource_type = orm.Column(orm.String(10), nullable=False)
    resource_id = orm.Column(orm.String(10), index=True)
    action_name = orm.Column(orm.String(10), nullable=False)
    result = orm.Column(orm.String(30),
                        default=u'成功',
                        server_default=u'成功')
    action_at = orm.Column(orm.TIMESTAMP,
                           default=sa.text('CURRENT_TIMESTAMP'),
                           server_default=sa.text('CURRENT_TIMESTAMP'))
